﻿using AppSocketModel;
using AppSocketService.Account;
using BCGPSCommon;
using BCGPSMongoData;
using LJD.IMS.Utility;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Text;

namespace AppSocketService.Location
{
    public class LocationPersonService : ServiceBase, ILocationPersonService
    {
        #region var
        // 个人账户设备位置表 
        private readonly MongoDBCommand<LocationDto> mongoCommand = new MongoDBCommand<LocationDto>("AccountVehicleLocation");
        private readonly GCJ02_WGS84_TransTools gCJ02_WGS84_TransTools = new GCJ02_WGS84_TransTools();
        private readonly IRedisService redisService; 
        private readonly AccountDto CurrentAccount;
        private readonly IAccountPersonService  accountPersonService;

        #endregion

        #region 构造函数
        public LocationPersonService(IClaimsAccessor claimsAccessor, IRedisService redisService, IAccountPersonService accountPersonService) : base(claimsAccessor)
        {
            this.redisService = redisService;
            this.accountPersonService = accountPersonService;
            CurrentAccount = accountPersonService.GetCurrentAccount();
        }

        public LocationPersonService (IRedisService redisService )
        {
            this.redisService = redisService;
        }
        #endregion

        #region 初始化Redis
        public List<LocationDto > InitRedisGetListAll()
        {
            return mongoCommand.SelectDocumentsAsync(s => s.CompanyId == 0).GetAwaiter().GetResult();
        }
        #endregion

        #region 修改车辆信息 根据 IMEI
        public LocationDto UpdateByImei(string vehicleNo, string Imei)
        {
            if (CurrentAccount.CompanyId > 0)
                return UpdateImeiCompany(vehicleNo, Imei);
            else
                return UpdateImeiPerson(vehicleNo, Imei);

        }
        private LocationDto UpdateImeiCompany(string vehicleNo, string Imei)
        {
                var update = Builders<LocationDto>.Update
                    .Set(s => s.VehicleNo, vehicleNo);
                return mongoCommand.UpdateDocumentAsync(s => s.CompanyId == CurrentAccount.CompanyId && s.IMEI == Imei, update).GetAwaiter().GetResult();

        }

        private LocationDto UpdateImeiPerson(string vehicleNo,string Imei)
        {   
                var update = Builders<LocationDto>.Update
                    .Set(s => s.VehicleNo, vehicleNo);
                return mongoCommand.UpdateDocumentAsync(s => s.CompanyId == 0 && s.AccountId == CurrentAccount.AccountId && s.IMEI == Imei, update).GetAwaiter().GetResult(); 
        }
        #endregion

        #region 添加一个设备位置
        public LocationDto AddNew(LocationDto locationDto)
        {
            if (string.IsNullOrWhiteSpace(locationDto.IMEI))
                throw new ArgumentException("IMEI必须填写!");

            if (CurrentAccount.CompanyId > 0)
                return AddNewCompany(locationDto);
            else
                return AddNewPerson(locationDto);
        }
        private LocationDto AddNewCompany(LocationDto locationDto)
        { 
            locationDto.CompanyId = CurrentAccount.CompanyId;
            locationDto.AccountId = CurrentAccount.ParentAccountId;
            mongoCommand.InsertDocumentAsync(locationDto).GetAwaiter().GetResult(); 
            return locationDto; 
        }
        private LocationDto AddNewPerson(LocationDto locationDto )
        { 
            locationDto.CompanyId = CurrentAccount.CompanyId;
            locationDto.AccountId = CurrentAccount.AccountId;
            mongoCommand.InsertDocumentAsync(locationDto).GetAwaiter().GetResult(); 
            return locationDto;
        }
        #endregion
               
        #region 删除指定账户的设备位置信息
        public void Delete(string imei)
        {
            if(CurrentAccount.CompanyId>0)
            { 
                mongoCommand.DeleteDocumentAsync(s =>s.CompanyId == CurrentAccount.CompanyId  && s.IMEI == imei).GetAwaiter().GetResult(); 
            }
            else
            {
                mongoCommand.DeleteDocumentAsync(s=>s.CompanyId == CurrentAccount.CompanyId && s.AccountId == CurrentAccount.AccountId && s.IMEI == imei).GetAwaiter().GetResult();
            }
        }
        #endregion
         
        #region 获取IMEI定位信息
        public LocationDto GetLocation(string imei, GpsMapType gpsMapType)
        {
            LocationDto ret = redisService.Get<LocationDto>(GeneralContainer.RedisNameSpaceIMEILocation + imei);
            if (ret == null)
            { 
                 ret = mongoCommand.SelectDocumentAsync(s => s.CompanyId == CurrentAccount.CompanyId && s.IMEI == imei).GetAwaiter().GetResult(); 
            }
            if (ret != null)
            {
                LocateInfo info;
                if (ret.Location == LocationType.LBS.ToString())
                {
                    info = new LocateInfo();
                    switch (gpsMapType)
                    {
                        case GpsMapType.GDMAP:
                            ret.Lat = ret.Lat;
                            ret.Lng = ret.Lng;
                            break;
                        case GpsMapType.BAIDUMAP:
                            info = gCJ02_WGS84_TransTools.Gcj02_To_bd09(ret.Lat, ret.Lng);
                            ret.Lat = info.Latitude;
                            ret.Lng = info.longitude;
                            break;
                    }

                }
                else
                {
                    switch (gpsMapType)
                    {
                        case GpsMapType.GDMAP:
                            info = gCJ02_WGS84_TransTools.wgs84_To_Gcj02(ret.Lat, ret.Lng);
                            ret.Lat = info.Latitude;
                            ret.Lng = info.longitude;
                            break;
                        case GpsMapType.BAIDUMAP:
                            info = gCJ02_WGS84_TransTools.wgs84_To_Bd09(ret.Lat, ret.Lng);
                            ret.Lat = info.Latitude;
                            ret.Lng = info.longitude;
                            break;
                    }
                }
                if (ret.GpsTime.HasValue)
                {
                    TimeSpan span = DateTime.Now - ret.GpsTime.Value;
                    if (span.TotalSeconds > 60)
                    {
                        ret.GpsDeviceOnlineState = GpsDeviceOnlineState.OFFLINE;
                        ret.OffLineTime = new OffLineTimeDto();
                        ret.OffLineTime.Days = span.Days;
                        ret.OffLineTime.Hours = span.Hours;
                        ret.OffLineTime.Minutes = span.Minutes;
                        ret.GpsDeviceSpeedState = null;
                    }
                    else
                    {
                        ret.GpsDeviceOnlineState = GpsDeviceOnlineState.ONLINE;
                        if (ret.Speed > 0.01)
                            ret.GpsDeviceSpeedState = GpsDeviceSpeedState.RUN;
                        else
                            ret.GpsDeviceSpeedState = GpsDeviceSpeedState.STOP;
                        ret.OffLineTime = null;
                    }
                }
                else
                {
                    ret.GpsDeviceOnlineState = GpsDeviceOnlineState.OFFLINE;
                    ret.GpsDeviceSpeedState = null;
                    ret.OffLineTime = null;
                }
            }
            return ret;
        }
        #endregion 
         
    }
}
